﻿// Fill out your copyright notice in the Description page of Project Settings.


#include "Slate/SGKConfigTab.h"
#include "GKConfigEditorStyle.h"
#include "GKConfigSetting.h"
#include "SlateOptMacros.h"
#include "Common/ConfigFileManager.h"
#include "Widgets/Images/SImage.h"
#include "Widgets/Layout/SScrollBox.h"
#include "Widgets/Input/SMultiLineEditableTextBox.h"

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION

void SGKConfigTab::Construct(const FArguments& InArgs)
{
	// GetConfigPath();
	ChildSlot
	[
		SNew(SBorder)
		.BorderImage(FGKConfigEditorStyle::StyleInstance->GetBrush("GKConfigEditor.OpenPluginWindow"))
        .Padding(20.f)
        .VAlign(VAlign_Fill)
        .HAlign(HAlign_Fill)
        [
        	SNew(SHorizontalBox)
        	+SHorizontalBox::Slot()
            .Padding(20.f,0.f,20.f,0.f)
            .VAlign(VAlign_Fill)
            .HAlign(HAlign_Fill)
            .FillWidth(0.3f)
            [
				SNew(SVerticalBox)
				+SVerticalBox::Slot()
				.Padding(0.f)
				.VAlign(VAlign_Fill)
				.HAlign(HAlign_Right)
				.AutoHeight()
				[
	
					SNew(SHorizontalBox)
                	+SHorizontalBox::Slot()
                	.Padding(10.f)
                	.VAlign(VAlign_Fill)
                	.HAlign(HAlign_Fill)
                	.AutoWidth()
                	[
                		SNew(SBox)
                		.WidthOverride(40.f)
                		.HeightOverride(40.f)
                		[
                			SAssignNew(AddButton, SButton)
                		]
					]
	
					+SHorizontalBox::Slot()
                    .Padding(10.f)
                    .VAlign(VAlign_Fill)
                    .HAlign(HAlign_Fill)
                    .AutoWidth()
                    [
                        SNew(SBox)
                        .WidthOverride(40.f)
                        .HeightOverride(40.f)
                        [
                            SAssignNew(DeleteButton, SButton)
                        ]
                    ]
				]
	
				+SVerticalBox::Slot()
                .Padding(0.f)
                .VAlign(VAlign_Fill)
                .HAlign(HAlign_Fill)
                .FillHeight(1.f)
                [
					SAssignNew(ConfigList, SScrollBox)
                ]
            ]
	
            +SHorizontalBox::Slot()
            .Padding(0.f)
            .VAlign(VAlign_Fill)
            .HAlign(HAlign_Fill)
            .FillWidth(1.f)
            [
                SNew(SVerticalBox)
                +SVerticalBox::Slot()
                .Padding(0.f)
            	.VAlign(VAlign_Fill)
            	.HAlign(HAlign_Fill)
            	.FillHeight(1.f)
                [
                    SAssignNew(ConfigContentBox, SMultiLineEditableTextBox)
                    .Text(this,&SGKConfigTab::GetConfigContentText)
                    .OnTextChanged(this, &SGKConfigTab::OnConfigChanged)
                ]
	
                +SVerticalBox::Slot()
               .Padding(20.f)
               .VAlign(VAlign_Fill)
               .HAlign(HAlign_Right)
               .AutoHeight()
               [
					SNew(SButton)
					.OnClicked(this, &SGKConfigTab::ClickSaveButton)
					[
						SNew(STextBlock)
                        .Text(FText::FromString("Save"))
					]
               ]
            ]
        ]
	];
	InitConfigButton();
}

void SGKConfigTab::InitConfigButton()
{
	ConfigButtons.Reset();
	TArray<FDirectoryPath> Temp=GetConfigPath();
	struct DirectoryVisitor : public IPlatformFile::FDirectoryVisitor
	{
		DirectoryVisitor(bool IncludeDirectory, bool IncludeFile): InIncludeDirectory(IncludeDirectory), InIncludeFile(IncludeFile) {}
		bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory) override
		{
			bool Result;
			if (InIncludeDirectory && bIsDirectory) Result = true;
			else if (InIncludeFile && !bIsDirectory) Result = true;
			else Result = false;
			if (Result) DirectoryPaths.Push(FilenameOrDirectory);
			return true;
		}

		bool InIncludeDirectory;
		bool InIncludeFile;
		TArray<FString> DirectoryPaths;
	};
	for(const auto& Directory:Temp)
	{
		DirectoryVisitor Visitor(false, true);
		IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
		FileManager.IterateDirectory(*Directory.Path, Visitor);
		for(const auto& ConfigPath:Visitor.DirectoryPaths)
		{
			AddConfigButton(ConfigPath);
		}
	}
	if (ConfigButtons.Num() > 0)
	{
		CurrentConfigIndex = ConfigButtons[0];
		CurrentConfigIndex->IsCurrent = true;
	} else
	{
		CurrentConfigIndex = nullptr;
	}
	ConfigContentBox->SetIsReadOnly(CurrentConfigIndex == nullptr);
}

void SGKConfigTab::AddConfigButton(FString ConfigPath)
{
	FString ConfigFileName= ConfigFileManager::GetFileNameFromPath(ConfigPath);
	if(ConfigFileName.EndsWith("ini"))
	{
		ConfigInfo* Temp = new ConfigInfo(ConfigPath, ConfigFileName);
		ConfigButtons.Push(Temp);
		ConfigList->AddSlot()
        .Padding(0.f,20.f,0.f,0.f)
        [
            SAssignNew(Temp->ConfigButton, SButton)
            .IsEnabled(this, &SGKConfigTab::IsImportButtonEnabled, Temp)
            .OnClicked(this, &SGKConfigTab::ClickConfigButton, Temp)
            .HAlign(HAlign_Fill)
            .VAlign(VAlign_Fill)
            [
            	SNew(SHorizontalBox)
            	+SHorizontalBox::Slot()
            	.Padding(20.f,0.f,0.f,0.f)
            	.HAlign(HAlign_Fill)
            	.VAlign(VAlign_Center)
            	.FillWidth(1.f)
            	[
					SNew(STextBlock)
					.Text(FText::FromString(ConfigFileName))
            	]

            	+SHorizontalBox::Slot()
                .Padding(20.f,0.f,20.f,0.f)
                .HAlign(HAlign_Right)
                .VAlign(VAlign_Center)
                [
					SNew(SBox)
					.WidthOverride(15.f)
					.HeightOverride(15.f)
					.Padding(0.f)
					.HAlign(HAlign_Fill)
					.VAlign(VAlign_Fill)
					[
						SNew(SImage)
                        .Image(FGKConfigEditorStyle::StyleInstance->GetBrush("GKConfigEditor.OpenPluginWindow"))
                        .Visibility(this, &SGKConfigTab::IsConfigEdited, Temp)
					]
                ]
            ]
        ];
	}
}

FReply SGKConfigTab::ClickConfigButton(ConfigInfo* Config)
{
	if(!Config->IsCurrent)
	{
		CurrentConfigIndex->IsCurrent = false;
		CurrentConfigIndex = Config;
		CurrentConfigIndex->IsCurrent = true;
		if(CurrentConfigIndex->IsSaved)
		{
			CurrentConfigIndex->ConfigContent = FText::FromString(ConfigFileManager::LoadConfigFileToString(CurrentConfigIndex->FilePath));
		}
	}
	return FReply::Handled();
}

FReply SGKConfigTab::ClickSaveButton()
{
	FString Temp = ConfigContentBox->GetText().ToString();
	ConfigFileManager::SaveConfigFile(Temp, CurrentConfigIndex->FilePath);
	CurrentConfigIndex->IsSaved = true;
	return FReply::Handled();
}

void SGKConfigTab::OnConfigChanged(const FText& NewContent)
{
	if(CurrentConfigIndex!=nullptr)
	{
		CurrentConfigIndex->IsSaved = false;
		CurrentConfigIndex->ConfigContent = NewContent;
	}
}

FText SGKConfigTab::GetConfigContentText() const
{
	if(CurrentConfigIndex) return CurrentConfigIndex->ConfigContent;
	return FText::FromString("");
	
}

EVisibility SGKConfigTab::IsConfigEdited(ConfigInfo* Config) const
{
	return Config->IsSaved ? EVisibility::Collapsed : EVisibility::Visible;
}

bool SGKConfigTab::IsImportButtonEnabled(ConfigInfo* Config) const
{
	return !Config->IsCurrent;
}

END_SLATE_FUNCTION_BUILD_OPTIMIZATION

TArray<FDirectoryPath> SGKConfigTab::GetConfigPath()
{
	TArray<FDirectoryPath> Result = GetMutableDefault<UGKConfigSetting>()->ConfigPath;
	return Result;
}
